package com.gqyin.demo.dao.impl;

import com.gqyin.demo.dao.BaseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import javax.validation.constraints.NotNull;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * @author guiqing.yin
 * 2024-04-07 16:37
 */
@Repository
public abstract class BaseRepositoryImpl<T, ID> implements BaseRepository<T, ID> {
    public final MongoTemplate mongoTemplate;
    private final Class<T> entityClass;

    @SuppressWarnings("unchecked")
    @Autowired
    public BaseRepositoryImpl(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
        // 通过反射获取实体类的类型
        this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    @Override
    public List<T> findAll() {
        return mongoTemplate.findAll(entityClass);
    }

    @Override
    public T findById(@NotNull ID id) {
        return mongoTemplate.findById(id, entityClass);
    }

    @Override
    public Page<T> findByPage(@NotNull PageRequest pageRequest) {
        Query query = new Query();
        List<T> result = mongoTemplate.find(query.with(pageRequest), entityClass);
        long total = mongoTemplate.count(query, entityClass);
        return new PageImpl<>(result, pageRequest, total);
    }

    @Override
    public T save(@NotNull T t) {
        return mongoTemplate.save(t);
    }

    @Override
    public T deleteById(@NotNull ID id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findAndRemove(query, entityClass);
    }
}
